#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <execinfo.h>
#include <unistd.h>

void ShowStack()
{
    int i;
    void * buffer[1024];
    int n = backtrace(buffer, 1024);
    char ** symbols = backtrace_symbols(buffer, n);
    for (i = 0; i < n; i++)
    {
        printf("%s\n", symbols[i]);
    }
}

void SigSegvProc(int signo)
{
    if (signo == SIGSEGV)
    {
        printf("Receive SIGSEGV signal\n");
    }
    else if (signo == SIGBUS)
    {
        printf("Receive SIGBUS signal\n");
    }
    else if (signo == SIGILL)
    {
        printf("Receive SIGSEGV signal\n");
    }
    else
    {
        printf("this is sig %d", signo);
    }
    ShowStack();
    exit(-1);
}

void RegSig()
{
    signal(SIGSEGV, SigSegvProc);
    signal(SIGBUS, SigSegvProc);
    signal(SIGILL, SigSegvProc);
}

void func6()
{
    raise(SIGILL);
}

void func5()
{
    func6();
}


void func4()
{
    raise(SIGBUS);
}

void func3()
{
    func4();
}


void func2()
{
    raise(SIGSEGV);
}

void func1()
{
    func2();
}

int main(int argc, char ** argv)
{
    argc = 2;
    argv[1] = "SIGSEGV";
    
    if (2 != argc)
    {
        printf("input SIGSEGV or SIGBUS or SIGILL");
        return 0;
    }
    
    RegSig();
    
    if (!strcmp("SIGSEGV", argv[1]))
    {
        func1();
    }
    else if (!strcmp("SIGBUS", argv[1]))
    {
        func3();
    }
    else if (!strcmp("SIGILL", argv[1]))
    {
        func5();
    }
    
    return 0;
}
